<?php
/**
 * Implementation of PHP Speedy for Joomla1.5
 * @copyright www.fijiwebdesign.com
 * @author gabe@fijiwebdesign.com
 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, http://aciddrop.com/php-speedy/
 */

// included only
defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed!' );

jimport( 'joomla.plugin.plugin' );

/**
 * Joomla PHP Speedy Integration
 *
 * @author gabe@fijiwebdesign.com
 */
class  plgSystemBot_Speedy extends JPlugin
{
	/**
	 * Constructor
	 *
	 * For php4 compatability we must not use the __constructor as a constructor for plugins
	 * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
	 * This causes problems with cross-referencing necessary for the observer design pattern.
	 *
	 * @access	protected
	 * @param	object $subject The object to observe
	 * @param 	array  $config  An array that holds the plugin configuration
	 * @since	1.0
	 */
	function plgSystemBot_Speedy(& $subject, $config)
	{
		parent::__construct($subject, $config);

	}

	/**
	* Load Pluging
	*/
	function onAfterRender()
	{
		$params =& $this->params;

		$document	=& JFactory::getDocument();
		$doctype	= $document->getType();

		// Only render for HTML output
		if ( $doctype !== 'html' ) { 
			return; 
		}

		// See if config allows loading for this page
		if (!$this->_allowLoad()) {
			return;
		}
		
		// get the http resp body
		$body = JResponse::getBody();
		
		// check if we have HTML / not gzipped
		$is_html = stristr($body, '</html>');

		// tidy up xhtml
		if ($tidy = ($params->get('tidy') && $is_html)) {
			$body = $this->_tidy($body);
		}
		
		// load speedy
		$this->_loadSpeedy($is_html);
		
		// add comments
		if ($params->get('show_comments')) {
			$body = $this->_addComment($body, 	
				($tidy ? 'XHTML1.0 Validated and ' : '')
				.('Optimized by Joomla Speedy - www.fijiwebdesign.com')
			);
		}

		// optimize
		$body = $this->_compress($body);

		// set optimized xhtml as http resp body
		JResponse::setBody($body);
	}
	
	/**
	 * Check if speedy is set to load for this page
	 * @return Bool
	 */
	function _allowLoad() {
		
		$params =& $this->params;
		$mainframe =& JFactory::getApplication();
		$document	=& JFactory::getDocument();
		
		// detect backend
		if ($mainframe->isAdmin()) {
			return false;
		}
		
		// check if debug mode is on and not debugging
		if (!JRequest::getVar('speedy') && $params->get('debug_mode')) {
			return false;
		}
		
		// the executing component name
		$option = JRequest::getCmd('option', false);
		
		// don't allow compression for these components
		$not_options = array(
			'login',
			'logout',
			'com_logout',
			'com_login'
		);
		array_map('trim', $not_options);
		if (in_array($option, $not_options)) {
			return false;
		}
		
		// users blacklisted components, inclusive
		$disallowed_options = $params->get('disallowed_components', false);
		if ($disallowed_options) {
			$disallowed_options = explode("\n", $options);
			array_map('trim', $disallowed_options);
			if (in_array($option, $disallowed_options)) {
				return false;
			}
		}
		
		// whitelisted components, exclusive
		$only_options = $params->get('allowed_components', false);
		if ($only_options) {
			$only_options = explode("\n", $only_options);
			array_map('trim', $only_options);
			if (!in_array($option, $only_options)) {

				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * Load the Speedy Plugin
	 * @return void
	 * @param $allow_gzip Bool[optional]
	 */
	function _loadSpeedy($allow_gzip = false) {
		
		$mainframe =& JFactory::getApplication();
		$document	=& JFactory::getDocument();
		$params =& $this->params;

		// get the base path
		$base_path = JPATH_BASE;
		$plug_path = str_replace('\\', '/', $base_path).'/plugins/system/';
		$live_site = JPATH_SITE;
	
		//We need these
		require($plug_path.'/php_speedy/controller/compressor.php');
		require($plug_path.'/php_speedy/libs/php/view.php'); //Include this for path getting help
		//chdir($cwd);
		
		//We need to know the config
		#########################################
		## Compressor option file ##############
		#########################################
		## Access control
		//$compress_options['username'] = "21232f297a57a5a743894a0e4a801fc3";
		//$compress_options['password'] = "4fe705bb8b349da9588e746cda9dbe2d";
		## Path info
		$opts['document_root'] = $_SERVER['DOCUMENT_ROOT'];
		
		//var_dump(array($opts['document_root'], $plug_path));
		//die;
		
		$opts['javascript_cachedir'] = $plug_path.'php_speedy/cache/js/';
		$opts['css_cachedir'] = $plug_path.'php_speedy/cache/css/';
		## Minify options
		$opts['minify']['javascript'] = $params->get('minify_js', '0');
		$opts['minify']['page'] = $params->get('minify_page', '0');
		$opts['minify']['css'] = $params->get('minify_css', '0');
		## Gzip options
		$opts['gzip']['javascript'] = $params->get('gzip_js', '0');
		$opts['gzip']['page'] = $allow_gzip ? $params->get('gzip_page', '0') : 0;
		$opts['gzip']['css'] = $params->get('gzip_css', '0');
		## Versioning
		$opts['far_future_expires']['javascript'] = $params->get('far_future_expires_js', '0');
		$opts['far_future_expires']['css'] = $params->get('far_future_expires_css', '0');
		#########################################
		$opts['show_timer'] = $params->get('show_timer', '0');
		$hide_errors = $params->get('hide_errors', '0');
		
		if ($hide_errors) {
			error_reporting(0);
		}
	
		//Con. the view library
		$view = new compressor_view();
		
		//Con. the js min library
		if(substr(phpversion(),0,1) == 5) {
			require_once($plug_path.'php_speedy/libs/php/jsmin.php');
			$jsmin = new JSMin(null);
		}
		
		//Con. the compression controller
		$this->compressor = new compressor(
			array('view'=>$view,
			   'options'=>$opts,
			   'jsmin'=>$jsmin)
		 );
	}
	
	/**
	 * Compress the Page with PHP Speedy
	 * @return void
	 * @param $body String Page HTML
	 */
	function _compress($body) {
		$body = $this->compressor->finish($body);
		return $body;
	}
	
	/**
	 * Append a Comment to the response Text
	 * @return void
	 * @param $body Response Body
	 * @param $text String
	 */
	function _addComment($body, $text) {
		$body .= "\n<!-- $text -->";
		return $body;
	}
	
	/**
	* Parses the HTML with PHP Tidy for W3C XHTML/CSS Compliance
	* @param String HTML
	*/
	function _tidy($html) {
		if (function_exists('tidy_parse_string')) {
			
			// Specify configuration
			$config = array(
					   'indent'         => true,
					   'output-xhtml'   => true,
					   'wrap'           => 200);
			// get Joomla content encoding
			$iso = split( '=', _ISO );
			$encoding = '';
			$jos_enc = str_replace('-', '', $iso[1]);
			if (in_array($jos_enc, array('ascii', 'latin0', 'latin1', 'raw', 'utf8', 'iso2022', 'mac', 'win1252', 'ibm858', 'utf16', 'utf16le', 'utf16be', 'big5', 'shiftjis'))) {
				$encoding = $jos_enc;
			}
			
			// Tidy
			$html = tidy_repair_string($html, $config, $encoding);

		}
		return $html;
	}

}

?>
